const express = require('express');
const { Op, sequelize } = require('sequelize');
const { Badge, User, Activity, ActivityParticipant } = require('../models');
const { authenticateToken, optionalAuth, isAdmin } = require('../middleware/auth');
const { validatePagination } = require('../middleware/validation');
const blockchainService = require('../services/blockchainService');

const router = express.Router();

// 获取徽章列表
router.get('/', optionalAuth, validatePagination, async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 100;
    const offset = (page - 1) * limit;
    const { user_id, filter } = req.query;

    console.log(`🔍 Badge API called with filter: ${filter}, user: ${req.user?.id}`);

    let badges = [];
    let count = 0;

    // 获取所有活动 - 后面多个筛选条件都会用到
    const allActivities = await Activity.findAll({
      order: [['createdAt', 'DESC']]
    });
    console.log(`📊 系统中的活动总数: ${allActivities.length}`);

    // 获取用户已获得的勋章 - 后面多个筛选条件都会用到
    let userOwnedBadges = [];
    let userOwnedActivityIds = new Set();
    if (req.user) {
      userOwnedBadges = await Badge.findAll({
        where: { 
          user_id: req.user.id,
          status: 'minted'
        },
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'username', 'avatar_url']
          },
          {
            model: Activity,
            as: 'activity',
            attributes: ['id', 'title', 'location', 'start_time']
          }
        ]
      });
      
      // 提取用户已获得勋章的活动ID
      userOwnedActivityIds = new Set(
        userOwnedBadges
          .map(badge => badge.activity_id)
          .filter(id => id !== null && id !== undefined)
      );
    }
    console.log(`👤 用户已获得勋章数量: ${userOwnedBadges.length}`);
    console.log(`👤 用户已获得勋章活动ID: ${[...userOwnedActivityIds].join(', ') || '无'}`);

    if (filter === 'owned' && req.user) {
      // 筛选：我的勋章 - 只显示用户拥有的勋章
      
      // 转换为JSON并添加isOwned标记
      badges = userOwnedBadges.map(badge => {
        const badgeJson = badge.toJSON();
        badgeJson.isOwned = true;
        return badgeJson;
      });
      
      count = badges.length;
      console.log(`📊 我的勋章: ${count}个`);
      
      // 应用分页
      badges = badges.slice(offset, offset + limit);
      
    } else if (filter === 'available') {
      // 筛选：可获得勋章 - 只显示用户未获得的勋章
      
      let availableBadges = [];
      
      // 处理每个活动，检查用户是否已获得该活动的勋章
      for (const activity of allActivities) {
        // 检查用户是否已获得此活动的勋章
        const userHasBadge = userOwnedActivityIds.has(activity.id);
        
        if (!userHasBadge) {
          // 用户未获得此活动的徽章，添加为可获得徽章
          const availableBadge = {
            id: `potential_${activity.id}`, // 使用特殊ID标识潜在勋章
            badge_name: `${activity.title} 参与徽章`,
            badge_description: `参与"${activity.title}"活动并签到即可获得此专属NFT徽章`,
            badge_image_url: null, // 未获得的勋章使用默认图片
            status: 'available',
            minted_at: null,
            user_id: null,
            activity_id: activity.id,
            activity: {
              id: activity.id,
              title: activity.title,
              location: activity.location,
              start_time: activity.start_time
            },
            user: null,
            isOwned: false
          };
          
          availableBadges.push(availableBadge);
          console.log(`➕ Adding available badge for activity ${activity.id}: ${activity.title}`);
        }
      }
      
      badges = availableBadges;
      count = badges.length;
      console.log(`📊 可获得勋章: ${count}个`);
      
      // 应用分页
      badges = badges.slice(offset, offset + limit);
      
    } else {
      // 筛选：全部勋章 - 显示所有勋章（已获得 + 未获得）
      
      // 1. 先添加用户已获得的勋章
      let allBadges = [];
      
      if (userOwnedBadges.length > 0) {
        // 添加用户已获得的勋章
        allBadges = userOwnedBadges.map(badge => {
          const badgeJson = badge.toJSON();
          badgeJson.isOwned = true;
          return badgeJson;
        });
      }
      
      // 2. 再添加用户未获得的勋章
      for (const activity of allActivities) {
        // 检查用户是否已获得此活动的勋章
        const userHasBadge = userOwnedActivityIds.has(activity.id);
        
        if (!userHasBadge) {
          // 用户未获得此活动的徽章，添加为可获得勋章
          const availableBadge = {
            id: `potential_${activity.id}`,
            badge_name: `${activity.title} 参与徽章`,
            badge_description: `参与"${activity.title}"活动并签到即可获得此专属NFT徽章`,
            badge_image_url: null,
            status: 'available',
            minted_at: null,
            user_id: null,
            activity_id: activity.id,
            activity: {
              id: activity.id,
              title: activity.title,
              location: activity.location,
              start_time: activity.start_time
            },
            user: null,
            isOwned: false
          };
          
          allBadges.push(availableBadge);
        }
      }
      
      badges = allBadges;
      count = badges.length;
      console.log(`📊 全部勋章: ${count}个（已获得: ${userOwnedBadges.length}个, 未获得: ${count - userOwnedBadges.length}个）`);
      
      // 应用分页
      badges = badges.slice(offset, offset + limit);
    }

    // 输出结果详情
    console.log(`🔍 返回结果: 第${page}页，每页${limit}个，返回${badges.length}个，总数${count}个`);

    res.json({
      badges,
      pagination: {
        page,
        limit,
        total: count,
        totalPages: Math.ceil(count / limit)
      }
    });
  } catch (error) {
    console.error('获取徽章列表失败:', error);
    res.status(500).json({
      error: '获取徽章列表失败'
    });
  }
});

// 获取徽章收集进度 - 必须放在/:id之前
router.get('/progress', authenticateToken, async (req, res) => {
  try {
    // 获取用户已收集的徽章数
    const earnedBadges = await Badge.count({
      where: { 
        user_id: req.user.id,
      }
    });

    // 获取可获得的徽章总数（基于已结束的活动）
    const availableBadges = await Activity.count({
      where: {
        end_time: { [Op.lt]: new Date() },
        status: 'completed'
      }
    });

    // 获取用户参与的活动数
    const participatedActivities = await ActivityParticipant.count({
      where: { 
        user_id: req.user.id,
        status: 'attended'
      }
    });

    // 获取最近获得的徽章
    const recentBadges = await Badge.findAll({
      where: { 
        user_id: req.user.id,
        status: 'minted'
      },
      include: [
        {
          model: Activity,
          as: 'activity',
          attributes: ['id', 'title', 'location']
        }
      ],
      order: [['createdAt', 'DESC']],
      limit: 5
    });

    // 计算收集进度百分比
    const progress = availableBadges > 0 ? 
      Math.round((earnedBadges / availableBadges) * 100) : 0;

    // 按类型统计徽章
    const badgeStats = {
      sports: 0,
      academic: 0,
      social: 0,
      volunteer: 0,
      creative: 0
    };

    // 这里应该根据活动类型来统计，简化处理
    const badgesByType = await Badge.findAll({
      where: { 
        user_id: req.user.id,
        status: 'minted'
      },
      include: [
        {
          model: Activity,
          as: 'activity',
          attributes: ['category_id']
        }
      ]
    });

    // 简单的类型映射（实际应该根据category表）
    badgesByType.forEach(badge => {
      const categoryId = badge.activity?.category_id || 1;
      if (categoryId <= 5) {
        const types = ['sports', 'academic', 'social', 'volunteer', 'creative'];
        badgeStats[types[categoryId - 1]]++;
      }
    });

    res.json({
      earned: earnedBadges,
      available: availableBadges,
      progress: progress,
      participatedActivities,
      recentBadges,
      badgeStats
    });
  } catch (error) {
    console.error('获取徽章进度失败:', error);
    res.status(500).json({
      error: '获取徽章进度失败'
    });
  }
});

// 获取徽章排行榜 - 必须放在/:id之前
router.get('/rankings/collectors', validatePagination, async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const offset = (page - 1) * limit;

    // 基于徽章数量排行
    const rankings = await User.findAll({
      attributes: [
        'id',
        'username',
        'avatar_url',
        [sequelize.fn('COUNT', sequelize.col('badges.id')), 'badge_count']
      ],
      include: [
        {
          model: Badge,
          as: 'badges',
          attributes: [],
          where: { status: 'minted' },
          required: false
        }
      ],
      group: ['User.id'],
      order: [[sequelize.fn('COUNT', sequelize.col('badges.id')), 'DESC']],
      limit,
      offset
    });

    res.json({
      rankings
    });
  } catch (error) {
    console.error('获取徽章排行榜失败:', error);
    res.status(500).json({
      error: '获取徽章排行榜失败'
    });
  }
});

// 获取徽章详情 - 放在具体路径之后
router.get('/:id', optionalAuth, async (req, res) => {
  try {
    const badge = await Badge.findByPk(req.params.id, {
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'avatar_url']
        },
        {
          model: Activity,
          as: 'activity',
          include: [
            {
              model: User,
              as: 'creator',
              attributes: ['id', 'username', 'avatar_url']
            }
          ]
        }
      ]
    });

    if (!badge) {
      return res.status(404).json({
        error: '徽章不存在'
      });
    }

    // 如果有token_id，尝试从区块链获取最新信息
    if (badge.token_id) {
      try {
        const metadata = await blockchainService.getBadgeMetadata(badge.token_id);
        if (metadata) {
          badge.blockchain_metadata = metadata;
        }
      } catch (error) {
        console.error('获取区块链元数据失败:', error);
      }
    }

    res.json(badge);
  } catch (error) {
    console.error('获取徽章详情失败:', error);
    res.status(500).json({
      error: '获取徽章详情失败'
    });
  }
});

// 铸造徽章（参与活动后自动调用）
router.post('/mint', authenticateToken, async (req, res) => {
  try {
    const { activity_id } = req.body;

    if (!activity_id) {
      return res.status(400).json({
        error: '活动ID不能为空'
      });
    }

    // 检查活动是否存在
    const activity = await Activity.findByPk(activity_id);
    if (!activity) {
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查用户是否参与了该活动并已签到
    const participation = await ActivityParticipant.findOne({
      where: {
        user_id: req.user.id,
        activity_id: activity_id,
        status: 'attended'
      }
    });

    if (!participation) {
      return res.status(400).json({
        error: '只有已签到的活动参与者才能获得徽章'
      });
    }

    // 检查是否已经获得该活动的徽章
    const existingBadge = await Badge.findOne({
      where: {
        user_id: req.user.id,
        activity_id: activity_id
      }
    });

    if (existingBadge) {
      return res.status(400).json({
        error: '您已经获得了该活动的徽章'
      });
    }

    // 创建徽章
    const badge = await Badge.create({
      user_id: req.user.id,
      activity_id: activity_id,
      badge_name: `${activity.title}参与徽章`,
      badge_description: `参与活动"${activity.title}"获得的纪念徽章`,
      badge_image_url: '/uploads/default-badge.svg',
      metadata: {
        activity_title: activity.title,
        activity_date: activity.start_time,
        activity_location: activity.location
      },
      status: 'minted',
      minted_at: new Date()
    });

    res.json({
      message: '徽章铸造成功',
      badge
    });
  } catch (error) {
    console.error('徽章铸造失败:', error);
    res.status(500).json({
      error: '徽章铸造失败'
    });
  }
});

// 转移徽章
router.post('/:id/transfer', authenticateToken, async (req, res) => {
  try {
    const { to_address } = req.body;

    if (!to_address) {
      return res.status(400).json({
        error: '目标地址不能为空'
      });
    }

    const badge = await Badge.findByPk(req.params.id);

    if (!badge) {
      return res.status(404).json({
        error: '徽章不存在'
      });
    }

    // 检查权限
    if (badge.user_id !== req.user.id) {
      return res.status(403).json({
        error: '无权限转移此徽章'
      });
    }

    // 检查徽章状态
    if (badge.status !== 'minted') {
      return res.status(400).json({
        error: '只有已铸造的徽章才能转移'
      });
    }

    // 这里应该调用区块链转移功能
    // 现在只是模拟转移
    res.json({
      message: '徽章转移功能暂未实现',
      note: '需要实现区块链转移合约功能'
    });
  } catch (error) {
    console.error('转移徽章失败:', error);
    res.status(500).json({
      error: '转移徽章失败'
    });
  }
});

// 验证徽章所有权
router.get('/:tokenId/verify/:userAddress', async (req, res) => {
  try {
    const { tokenId, userAddress } = req.params;

    const isOwner = await blockchainService.verifyBadgeOwnership(tokenId, userAddress);

    res.json({
      tokenId,
      userAddress,
      isOwner
    });
  } catch (error) {
    console.error('验证徽章所有权失败:', error);
    res.status(500).json({
      error: '验证徽章所有权失败'
    });
  }
});

// 获取徽章统计信息
router.get('/stats/overview', async (req, res) => {
  try {
    const totalBadges = await Badge.count();
    
    const badgesByRarity = await Badge.findAll({
      attributes: [
        'rarity',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      group: ['rarity']
    });

    const badgesByStatus = await Badge.findAll({
      attributes: [
        'status',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      group: ['status']
    });

    const recentBadges = await Badge.findAll({
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'avatar_url']
        },
        {
          model: Activity,
          as: 'activity',
          attributes: ['id', 'title']
        }
      ],
      order: [['minted_at', 'DESC']],
      limit: 10
    });

    res.json({
      totalBadges,
      badgesByRarity,
      badgesByStatus,
      recentBadges
    });
  } catch (error) {
    console.error('获取徽章统计失败:', error);
    res.status(500).json({
      error: '获取徽章统计失败'
    });
  }
});

// 获取用户徽章统计
router.get('/stats/user/:userId', async (req, res) => {
  try {
    const userId = req.params.userId;

    const totalBadges = await Badge.count({
      where: { user_id: userId }
    });

    const badgesByRarity = await Badge.findAll({
      where: { user_id: userId },
      attributes: [
        'rarity',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      group: ['rarity']
    });

    const badgesByStatus = await Badge.findAll({
      where: { user_id: userId },
      attributes: [
        'status',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      group: ['status']
    });

    const firstBadge = await Badge.findOne({
      where: { user_id: userId },
      order: [['minted_at', 'ASC']],
      include: [
        {
          model: Activity,
          as: 'activity',
          attributes: ['id', 'title']
        }
      ]
    });

    const latestBadge = await Badge.findOne({
      where: { user_id: userId },
      order: [['minted_at', 'DESC']],
      include: [
        {
          model: Activity,
          as: 'activity',
          attributes: ['id', 'title']
        }
      ]
    });

    res.json({
      totalBadges,
      badgesByRarity,
      badgesByStatus,
      firstBadge,
      latestBadge
    });
  } catch (error) {
    console.error('获取用户徽章统计失败:', error);
    res.status(500).json({
      error: '获取用户徽章统计失败'
    });
  }
});

// 检查区块链网络状态
router.get('/blockchain/status', async (req, res) => {
  try {
    const status = await blockchainService.checkNetworkStatus();
    res.json(status);
  } catch (error) {
    console.error('检查区块链状态失败:', error);
    res.status(500).json({
      error: '检查区块链状态失败'
    });
  }
});

// 估算Gas费用
router.post('/estimate-gas', authenticateToken, async (req, res) => {
  try {
    const { activity_id, badge_data } = req.body;

    const user = await User.findByPk(req.user.id);
    if (!user.wallet_address) {
      return res.status(400).json({
        error: '用户未设置钱包地址'
      });
    }

    const gasEstimate = await blockchainService.estimateGasFee(
      user.wallet_address,
      activity_id,
      badge_data
    );

    res.json({
      gasEstimate
    });
  } catch (error) {
    console.error('估算Gas费用失败:', error);
    res.status(500).json({
      error: '估算Gas费用失败'
    });
  }
});

// 获取徽章发放记录（管理员）
router.get('/records', authenticateToken, isAdmin, async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const offset = (page - 1) * limit;

    console.log(`开始查询徽章发放记录: 第${page}页, 每页${limit}条`);

    // 查询徽章记录
    const { count, rows: records } = await Badge.findAndCountAll({
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'avatar_url']
        },
        {
          model: Activity,
          as: 'activity',
          attributes: ['id', 'title']
        }
      ],
      order: [['createdAt', 'DESC']],
      limit,
      offset
    });

    console.log(`已查询到${count}条徽章记录`);

    res.json({
      records,
      pagination: {
        page,
        limit,
        total: count,
        totalPages: Math.ceil(count / limit)
      }
    });
  } catch (error) {
    console.error('获取徽章发放记录失败:', error);
    res.status(500).json({
      error: '获取徽章发放记录失败',
      message: error.message
    });
  }
});

module.exports = router; 